package competition;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;

import scg.gen.History;
import scg.gen.ParseException;
import utils.FileUtilities;
import utils.FormatUtilities;

import gamehistory.HistoryModel;
import gamehistory.utils.xml.XMLModel;

/**
 * 
 * @author Brent Kersanske
 *
 */
public class CompetitionModel extends XMLModel {
		
	private static final String MSG_INFO_FOUND_FILES			  = "[INFO] Directory {0} has {1} files.";
	private static final String MSG_ERROR_UNABLE_TO_PARSE_HISTORY = "[ERROR] An exception occurred while parsing history file {0}: {1}";	
	
	private static final String COMPETITION = "competition";
	private static final String DATE		= "date";
	private static final String NUM_GAMES	= "numberOfGames";
		
	private static final String DEFAULT_OUTPUT_DIRECTORY = "xml/";
	
	private String competitionDirectory;
	private String outputDirectory;
	private String date;
	private ArrayList<String> gameHistoryFileNames;
	
	
	public CompetitionModel(String competitionDirectory) {
		super(COMPETITION);
		this.competitionDirectory 				= competitionDirectory;
		this.outputDirectory	  			    = DEFAULT_OUTPUT_DIRECTORY;
		ArrayList<String> filesNamesInDirectory = FileUtilities.getFileNamesInDirectory(competitionDirectory);
		this.gameHistoryFileNames				= deriveGameHistoryFileNames(filesNamesInDirectory);
		System.out.println(MessageFormat.format(MSG_INFO_FOUND_FILES, this.competitionDirectory, this.gameHistoryFileNames.size()));
	}
	
	/**
	 * Constructor.
	 * @param competitionDirectory
	 */
	public CompetitionModel(String competitionDirectory, String outputDirectory) {
		super(COMPETITION);
		this.competitionDirectory 			    = competitionDirectory;
		this.outputDirectory	 			    = outputDirectory;
		ArrayList<String> filesNamesInDirectory = FileUtilities.getFileNamesInDirectory(competitionDirectory);
		this.gameHistoryFileNames				= deriveGameHistoryFileNames(filesNamesInDirectory);
		System.out.println(MessageFormat.format(MSG_INFO_FOUND_FILES, this.competitionDirectory, this.gameHistoryFileNames.size()));
	}
	
	/**
	 * Helper function to filter list of file names to history files.
	 * @param fileNames
	 * @return
	 */
	private ArrayList<String> deriveGameHistoryFileNames(ArrayList<String> fileNames) {
		ArrayList<String> historyFiles = new ArrayList<String> ();
		for(String fileName : fileNames) {
			if(fileName.contains("-vs-") && fileName.contains(".txt") && !fileName.contains("statistic")) {
				historyFiles.add(fileName);
			} else if(fileName.contains("history_".concat(String.valueOf(Calendar.YEAR)))) {
				historyFiles.add(fileName);
			}
		}
		return historyFiles;
	}
	
	/**
	 * 
	 */
	public void parseHistories() {
		for(String historyFileName : this.gameHistoryFileNames) {
			try {
				History gameHistory       = parseHistory(historyFileName);
				HistoryModel historyModel = new HistoryModel(gameHistory);
				historyModel.writeAssimilationsToXMLFiles(this.outputDirectory);
				historyModel.buildModel();
				addChildModel(historyModel);
				if(date == null){
					setCompetitionDate(historyFileName);
				}
			} catch(Exception e) {
				System.out.println(MessageFormat.format(MSG_ERROR_UNABLE_TO_PARSE_HISTORY, historyFileName, e.getMessage()));
			}
		}
	}	
	
	/**
	 * 
	 * @param historyFileName
	 * @return
	 * @throws FileNotFoundException
	 * @throws ParseException
	 */
	private History parseHistory(String historyFileName) throws FileNotFoundException, ParseException {
		File historyFile = new File(this.competitionDirectory.concat(historyFileName));
        if(!historyFile.isDirectory()) {
       		History gameHistory = History.parse(new FileInputStream(historyFile));
       		return gameHistory;
        } else {
        	throw new IllegalArgumentException("Provided file name {0} does not match criteria for parsing!");
        }
	}
	
	/**
	 * 
	 * @param historyFileName
	 */
	private void setCompetitionDate(String historyFileName) {
		StringBuilder theDate = new StringBuilder(historyFileName);
		theDate.delete(theDate.indexOf("tournament_"), "tournament_".length());
		String theYear = theDate.substring(0, 4);
		theDate.delete(theDate.indexOf(theYear), theYear.length() + 1);
		String theMonth = theDate.substring(0, 2);
		theDate.delete(0, 3);
		String theDay = theDate.substring(0, 2);
		theDate.delete(theDate.indexOf(theDay), theDay.length() + 1);		
		this.date = FormatUtilities.getFormattedDate(theYear, theMonth, theDay);		
	}
	
	/**
	 * 
	 */
	public void buildModel() {
		addAttribute(DATE, this.date);
		addAttribute(NUM_GAMES, String.valueOf(this.getNumChildren()));
	}
}
